import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.util.*;
import java.io.*;
import java.sql.*;
import java.util.zip.*;


public class SourceGen
{
	// variables for generate document
	// it is related to html file that is in DB
	// so if someone want to modify something from DB, below variables should be also considered
	static final String DATE = "DateHere";
	static final String INSTRUCTION = "InstructionsHere";
	static final String NUM_END = "NumEnd";
	static final String PART = "Part ";
	static final String JAR_FILE_NAME = "jar_instructions.html";
	static final String INST_FILE_NAME = "exam_instructions.html";
	static final String SCORE_SHEET = "ProgExamScoreSheetDateHere.html";
	Connection conn;

	/**
	 *	@param args
	 */
	public static void main(String[] args)
	{	
		String runCode = args[0];

		SourceGen sg = new SourceGen();
		try
		{
			sg.connect();
		}
		catch(SQLException sql)
		{
			sql.printStackTrace();
		}

		if(runCode.compareTo("generate")==0)
		{
			String date_scheduled = args[1];
			int author_id = Integer.parseInt(args[2]);
			sg.generate(date_scheduled, author_id);
		}
		else if(runCode.compareTo("package")==0)
		{
			int examID = Integer.parseInt(args[1]);
			sg.pack(examID);
		}

		try {
			sg.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	public void connect() throws SQLException {
		DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
		conn = DriverManager.getConnection("jdbc:oracle:thin:@146.187.134.17:1542:oracle10g", "cscd494",	"R3tral435");
	}

	public void close() throws SQLException 
	{
		conn.close();//Close database connection
	}

	public void generate(String date_scheduled, int author_id) 
	{
		ArrayList<CatAndPoints> qCategory;

		qCategory = getCategoryList();

	
		//Each index in qID is an ArrayList of question_id, which correspond
		//to the index of qCategory for the name of that category
		ArrayList[] qID = new ArrayList[qCategory.size()];
		
		//initialize each array and grab the question_id
		for(int i=0;i<qCategory.size();i++)
		{
			qID[i] = getCategoryQuestion(qCategory.get(i).cat);
		}
		
		previewExam(qCategory, qID, date_scheduled, author_id);
	}

	public void pack(int examID) {
		createExam(examID);// Generate an exam question
					
		/*try
		{//Archive all file for exam
			ZipOutputStream zos = new ZipOutputStream(new FileOutputStream("ape.zip"));
			sg.createZip("Solution",zos);
			sg.createZip("Student",zos);
			zos.close();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}*/
	}

	/**
	 * Grab a list of all the question type that question should be generated for.
	 * @param conn A database connection
	 * @return An ArrayList of all current type(category) of question available
	 */
	public ArrayList<CatAndPoints> getCategoryList()
	{
		ArrayList<CatAndPoints> array = new ArrayList<CatAndPoints>();
		try
		{
			Statement quesType = conn.createStatement();
			ResultSet rset = quesType.executeQuery(
			     "SELECT type_code, points, type_description FROM QUESTION_TYPE");
			while(rset.next())
			{
				array.add(new CatAndPoints(rset.getString("type_code"), 
				     rset.getInt("points"), rset.getString("type_description")));
			}
			quesType.close();
			rset.close();
		}
		catch(SQLException sqlError)
		{
			sqlError.printStackTrace();
		}

		return array;
	}

	/**
	 * This will return list of question_id for a type of question passed in.
	 * @param conn	A database connection
	 * @param questionCode	The type(category) of question to grab from database
	 * @return An ArrayList of all question_id for the type(category) specified by questionCode
	 */
	public ArrayList<QIdAndPoints> getCategoryQuestion(String questionCode)
	{
		ArrayList<QIdAndPoints> store = new ArrayList<QIdAndPoints>();
		try
		{
			PreparedStatement quesType = conn.prepareStatement(
			     "SELECT question_type_code, question_id, q_version, points "+
			     "FROM QUESTION_CONTENT INNER JOIN QUESTION "+
			     "ON QUESTION.question_content_id = "+
			          "QUESTION_CONTENT.question_content_id "+
			     "WHERE question_type_code = ? AND question.q_version="+
				       "(SELECT MAX(q_version) FROM question_content q "+
				            "WHERE q.question_id=question.question_id)");
			quesType.setString(1,questionCode);
			ResultSet r = quesType.executeQuery();
			while(r.next())
			{
				store.add(new QIdAndPoints(r.getInt("question_id"), r.getInt("q_version"),
				     r.getInt("points")));
			}
			r.close();//close the ResultSet
			quesType.close();//close Statement
		}
		catch(SQLException sqlError)
		{
			sqlError.printStackTrace();
		}

		return store;
	}

	/**
	 * Generate a list a potential question for an exam
	 * @param conn	A database connection
	 * @param qCategory	A list of question category
	 * @param qID	A list of question id
	 */
	public void previewExam(ArrayList<CatAndPoints> qCategory, ArrayList[] qID, String date_scheduled, int author_id)
	{
		ArrayList<Integer> examQuestion = new ArrayList<Integer>();
		
		int randNum = 0;
		int curPoints, curQID;
		int examID = SQLCall.getNextSeq(conn, "exam_s1");
		
		
		try
		{
			SimpleDateFormat df = new SimpleDateFormat(date_scheduled);
			java.sql.Date date = new java.sql.Date(new java.util.Date().getTime());
			try 
			{
				date = new java.sql.Date(df.parse(date_scheduled).getTime());
			}
			catch (ParseException e)
			{
				System.out.println("Date formated incorrectly");
			}

			PreparedStatement checkExam = conn.prepareStatement(
						"INSERT INTO exam "+
						"(exam_id, date_created, date_scheduled, author_id) "+
						"VALUES(?, SYSDATE, ?, ?)");
						
			checkExam.setInt(1, examID);
			checkExam.setDate(2, date);
			checkExam.setInt(3, author_id);
			checkExam.executeQuery();
			
			checkExam.close();
		}
		catch(SQLException sqlError)
		{
			sqlError.printStackTrace();
		}		  
		for(int i=0;i<qCategory.size();i++)
		{
			if(qID[i].size() == 0)
			{
				System.out.println("There are no question");
				break;
			}
			
			NoRepeatRandom randGen = new NoRepeatRandom();
			int remainPoints = qCategory.get(i).points;
			System.out.println("qID size: "+qID[i].size());
			while(remainPoints > 0)
			{
				if(qID[i].size()>0)
				{
					try
					{
						randNum = randGen.getNextInt(qID[i].size());
					
						System.out.println("randNum:"+randNum);
						
						curQID = ((QIdAndPoints)qID[i].get(randNum)).qId;
						curPoints = ((QIdAndPoints)qID[i].get(randNum)).points;
						
						if(remainPoints >= curPoints)
						{
							examQuestion.add(curQID);
							System.out.println("qid"+curQID);
							remainPoints -= curPoints;
						}
					}
					catch(Exception e)
					{
						e.printStackTrace();
					}
				}
			}
		}
		try
		{
			PreparedStatement uploadStmt = conn.prepareStatement(
			     "INSERT INTO EXAM_QUESTION (exam_id, question_id, q_version) "+
				  "VALUES(?,?, "+
			          "(SELECT MAX(q_version) FROM question q "+
			               "WHERE q.question_id=?)");
			uploadStmt.setInt(1,examID);
			for(int i=0;i<examQuestion.size();i++)
			{
				uploadStmt.setInt(2,(Integer)examQuestion.get(i));
				uploadStmt.setInt(3,(Integer)examQuestion.get(i));
				uploadStmt.execute();
			}
			uploadStmt.close();
		}
		catch(SQLException sqlError)
		{
			sqlError.printStackTrace();
		}
	}

	/**
	 * Grab all the file need for each questionID from the list
	 * @param conn A connection to the database
	 * @param questionID An ArrayList of question_id on this exam
	 */
	public void createExam(int examID)//, ArrayList<Integer> questionID)
	{
		ArrayList<Question> examQuestion = new ArrayList<Question>();
		
		/*int[] array={1,1};
		for(int i=0;i<1;i++)
		{
			String directory = "Part"+(i+1);
			new File("Student/" + directory).mkdirs();
			new File("Solution/" + directory).mkdirs();
			generateQuestion(conn,array[i], directory);
		}*/
		try
		{
			PreparedStatement pstmt = conn.prepareStatement(
			     "SELECT question_id, q_version FROM EXAM_QUESTION WHERE exam_id=?");
			pstmt.setInt(1,examID);
			ResultSet rset = pstmt.executeQuery();
			
			while(rset.next())
			{
				examQuestion.add(new Question(
				     rset.getInt("question_id"), rset.getInt("q_version"));
			}
			
			for(int i=0;i<examQuestion.size();i++)
			{
				String directory = "Part"+(i+1);
				new File("Student/" + directory).mkdirs();
				new File("Solution/" + directory).mkdirs();
				generateQuestion(examQuestion.get(i), directory);
			}
				//get date of exam to pass to instruction
				String date = getDate(examID);

				generateJar();
				generateInstruction(examQuestion, date);
				generateGradesheet(examQuestion, date, examID);
		}
		catch(SQLException sqlError)
		{
			sqlError.printStackTrace();
		}
	}

	/**
	 * Grab all the file need to generate a question. Eventually it will accept a question_id to generate more different question.
	 * @param conn A database connection
	 * @param qID	ID of the question
	 * @param pDirectory	The directory name where the file belong
	 */
	public void generateQuestion(Question q, int ver, String pDirectory)
	{
		try
		{
			// Grab Provided Output
			PreparedStatement qOutput = conn.prepareStatement(
			     "SELECT test_input, input_file_name, "+
			          "provided_input, provided_output "+
			     "FROM QUESTION_CONTENT INNER JOIN QUESTION "+
			     "ON QUESTION.QUESTION_CONTENT_ID = "+
			          "QUESTION_CONTENT.QUESTION_CONTENT_ID " +
			     "WHERE QUESTION_ID=? AND q_version="+
			          "question.q_version=(SELECT MAX(q_version) FROM question_content q "+
			               "WHERE q.q_version<=?)");
			qOutput.setInt(1,q.id);
			qOutput.setInt(2,ver);
			ResultSet qResult = qOutput.executeQuery();
			
			qResult.next();
			Blob outputBlob = qResult.getBlob("provided_output");

			if(outputBlob != null)
			{
				BufferedOutputStream sStream = new BufferedOutputStream(
				     new FileOutputStream(new File("Student/" + pDirectory, 
				          "sampleOutput.txt")));
				sStream.write(outputBlob.getBytes(1, (int)outputBlob.length()), 0, 
				     (int)outputBlob.length());//Write out the length of blob to file
				sStream.flush();
				sStream.close();
			}
			
			//Grab provided input
			String fname = null;
			fname = qResult.getString("input_file_name");
			Blob inputBlob = qResult.getBlob("provided_input");
			
			if(inputBlob != null)
			{
				BufferedOutputStream stuStream = new BufferedOutputStream(
				     new FileOutputStream(new File("Student/"+pDirectory, fname)));
				stuStream.write(inputBlob.getBytes(1, (int)inputBlob.length()), 0, 
				     (int)inputBlob.length());
				
				stuStream.flush();
				stuStream.close();
			}
			
			//Grab Test Input
			fname = qResult.getString("input_file_name");
			Blob testInputBlob = qResult.getBlob("test_input");
			
			if(testInputBlob != null)
			{
				BufferedOutputStream solStream = new BufferedOutputStream(
				     new FileOutputStream(new File("Solution/"+pDirectory, fname)));
				solStream.write(testInputBlob.getBytes(1, (int)testInputBlob.length()), 0, (int)testInputBlob.length());
				
				solStream.flush();
				solStream.close();
			}
			qResult.close();
			qOutput.close();
			
			
			//Grab Source File
			System.out.println(qID);
			PreparedStatement prepStatement = conn.prepareStatement(
			     "SELECT SOURCE_FILE.source_file_id AS \"File ID\", " +
			          "SOURCE_FILE.source_file_name AS \"File Name\","+
				       "SOURCE_FILE.source_file AS \"Source\" " +
			     "FROM SOURCE_FILE INNER JOIN QUESTION "+
			     "ON QUESTION.question_id = SOURCE_FILE.question_id " +
			     "WHERE QUESTION.question_id = ? AND q_version="+
			          "question.q_version=(SELECT MAX(q_version) FROM source_file q "+
			               "WHERE q.q_version<=?)");
			// NOTE: The above might require a change from question.q_version to
			// source_file.q_version...

			prepStatement.setInt(1,qID);//Change question_id
			prepStatement.setInt(2,ver);//Change question version
			
			ResultSet rset = prepStatement.executeQuery(); //run PreparedStatement

			while	(rset.next())//While the result is not empty
			{		
				String filename =	rset.getString("File Name");
				
				if(filename.toLowerCase().contains(".java"))//Check if the file is .Java
				{
					String curLine	= null;
					int index = 0;
					Scanner scan =	new Scanner(rset.getBinaryStream("Source"));

					PrintWriter	studentFile	= new	PrintWriter(
					     new File("Student/"+pDirectory,filename));
					PrintWriter	solutionFile =	new PrintWriter(
					     new File("Solution/"+pDirectory,filename));
					while(scan.hasNext())
					{
						curLine	= scan.nextLine();
						if((index = curLine.indexOf("/*ans bl*/")) >0)
						{
							int index2 = curLine.indexOf("/*ans ab*/")+10;
							String temp = curLine.substring(0,index);
							String temp1 = curLine.substring(index2,curLine.length());
							studentFile.printf(temp);
							studentFile.println(temp1);
							solutionFile.println(curLine);
							curLine = scan.nextLine();
						}
						if(curLine.equals("/*ans bl*/"))
						{
							curLine = scan.nextLine();
							while(!curLine.equals("/*ans ab*/"))
							{
								solutionFile.println(curLine);
								curLine = scan.nextLine();
							}
						}
						else
						{
							studentFile.println(curLine);
							solutionFile.println(curLine);
						}
					}
					studentFile.close();
					solutionFile.close();
				}
				else// if(filename.indexOf(".java")<0)//Not a java file don't need to parse
				{
					Blob blob = rset.getBlob("Source");
					BufferedOutputStream studentStream = 
					     new BufferedOutputStream(new FileOutputStream(
					          new File("Student/" + pDirectory, filename)));
					BufferedOutputStream solutionStream = 
					     new BufferedOutputStream(new FileOutputStream(
					          new File("Solution/" + pDirectory, filename)));

					studentStream.write(blob.getBytes(1, (int)blob.length()), 0, 
					     (int)blob.length());//Write out the length of blob to file
					solutionStream.write(blob.getBytes(1, (int)blob.length()), 0, 
					     (int)blob.length());

					studentStream.flush();
					solutionStream.flush();

					studentStream.close();
					solutionStream.close();
				}
			}
			rset.close();//Close ResultSet
			prepStatement.close();//Close PreparedStatement
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
	/**
	 * Grab jar file instruction from database. It will not change any content of the file.
	 */
	public void generateJar()
	{
		try
		{
			PreparedStatement stmt = conn.prepareStatement("select * FROM DOCUMENTS where DOCUMENT_NAME=?");
			stmt.setString(1, JAR_FILE_NAME);
			ResultSet rset = stmt.executeQuery();
	
			//read it as blob and just spit out to html because there is nothing to change
			rset.next();
			Blob b = rset.getBlob("DOCUMENT_FILE");
			BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(new File("Student", JAR_FILE_NAME)));
			os.write(b.getBytes(1, (int)b.length()), 0, (int)b.length());
			os.flush();
			os.close();
						
			stmt.close();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
	/**
	 * Grab exam instructions from database. It will modify some fields(date, instructions) that are needed to be changed from time to time.
	 * @param examQestion ArrayList that holds question id that is used for current exam
	 * @param date scheduled date for current exam
	 */
	public void generateInstruction(ArrayList<Integer> examQuestion, String date)
	{
		int numQ = examQuestion.size();
		try
		{
			PreparedStatement stmt = conn.prepareStatement("select * FROM DOCUMENTS where DOCUMENT_NAME=?");
			stmt.setString(1, INST_FILE_NAME);
			ResultSet rset = stmt.executeQuery();
			
			rset.next();
			Scanner inFile =	new Scanner(rset.getBinaryStream("DOCUMENT_FILE"));
			
			PrintWriter outFile = new PrintWriter(new File("Student/", INST_FILE_NAME));
			
			while(inFile.hasNext())
			{
				String s = inFile.nextLine();
				if(s.contains(DATE))
				{
					s = s.replace(DATE, date);
				}
				else if(s.contains(NUM_END))
				{
					s = s.replace(NUM_END, ((Integer)numQ).toString());
				}
				else if(s.contains(INSTRUCTION))
				{
					s = "";
					for(int i = 1; i <= numQ; i++)
					{
						s += "<li><u>" + PART + i + "</u>:&nbsp&nbsp";
						s += readInstruction(examQuestion.get(i-1));
						s += "</li><br><br>";
					}
				}
				outFile.println(s);
			}
			inFile.close();
			outFile.close();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
	/**
	 * Grab score sheet from database. It will modify grading criteria that are needed to be changed from time to time.
	 * @param examQestion ArrayList that holds question id that is used for current exam
	 * @param date scheduled date for current exam
	 */
	public void generateGradesheet(ArrayList<Integer> examQuestion, String date, int examID)
	{
		QuestionContents [] qContents = new QuestionContents [examQuestion.size()];
		for(int i = 0; i < examQuestion.size(); i++)
		{
			qContents[i] = getQuestionContents(examQuestion.get(i));
		}
		Arrays.sort(qContents);
		
		ArrayList<CatAndPoints> qCategory = new ArrayList<CatAndPoints>();
		qCategory = getCategoryList();
		
		try
		{			
			String fileName = SCORE_SHEET.replace(DATE, date);
			PrintWriter outFile = new PrintWriter(new File("Solution/", fileName));
			
			//put header
			outFile.println("<html><head><title>Program Exam Score Sheet ");
			outFile.println(date + "</title></head>");
			//put body
			outFile.println("<body><font face=\"Times\">");
			outFile.println("<table border=\"1\" cellpadding=\"0\" cellspacing=\"0\" bordercolor=\"black\">");
			outFile.println("<CAPTION align=\"left\">Test ID #:&nbsp&nbsp" + examID + "</CAPTION>");
			//start table
			outFile.println("<tr height=\"30\">");
			outFile.println("<th>Category</th><th>Scoring Criteria</th><th>Comments</th><th>Score</th>");
			outFile.println("</tr>");
			//put category from database
			for(int i = 0; i < qCategory.size(); i++)
			{
				outFile.println("<tr>");
				outFile.println("<td width=\"135\">");
				outFile.println(qCategory.get(i).description + "<br><br>");
				outFile.println(qCategory.get(i).points + " Points total</td>");
				outFile.println("<td width=\"370\">");
				for(int j = 0; j < qContents.length; j++)
				{
					if(qCategory.get(i).cat.equals(qContents[j].cat))
					{
						outFile.println("<b>" + qContents[j].title + "(" + qContents[j].points + " points possible):</b>&nbsp&nbsp");
						outFile.println(new String(qContents[j].criteria.getBytes(1, (int)qContents[j].criteria.length())));
						outFile.println("<br><br>");
					}
				}
				outFile.println("</td>");
				outFile.println("<td width=\"145\">&nbsp</td>");
				outFile.println("<td width=\"60\">&nbsp</td>");
				outFile.println("</tr>");
			}
			//end of table
			outFile.println("<tr height=\"30\">");
			outFile.println("<td><i><b>Total</b></i></td>");
			outFile.println("<td><i><b>Passing Score: 80</b></i></td>");
			outFile.println("<td>&nbsp</td><td>&nbsp</td></tr></table>");
			//put footer
			outFile.println("</font></body></html>");

			outFile.close();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
	/**
	 * get the neccessary info for the question whose id is qID. It will be used in generateGradesheet
	 * @param qID question ID to be searched
	 */
	public QuestionContents getQuestionContents(int qID, int ver)
	{
		String cat = "", title = "";
		Blob criteria = null;
		int points = 0;
		try
		{
			PreparedStatement stmt = conn.prepareStatement("select QUESTION_TYPE_CODE FROM QUESTION where QUESTION_ID=? AND q_version=?");
			stmt.setInt(1, qID);
			stmt.setInt(2, ver);
			ResultSet rset = stmt.executeQuery();
			
			rset.next();
			cat = rset.getString("QUESTION_TYPE_CODE");
			
			stmt.clearParameters();
			
			stmt = conn.prepareStatement("SELECT question_title, scoring_criteria, points FROM QUESTION_CONTENT INNER JOIN QUESTION ON QUESTION.QUESTION_CONTENT_ID = QUESTION_CONTENT.QUESTION_CONTENT_ID WHERE QUESTION_ID=? AND q_version="+
			          "question.q_version=(SELECT MAX(q_version) FROM question_content q "+
			               "WHERE q.q_version<=?)");
			stmt.setInt(1, qID);
			stmt.setInt(2, ver);
			rset = stmt.executeQuery();
			
			rset.next();
			title = rset.getString("QUESTION_TITLE");
			criteria = rset.getBlob("SCORING_CRITERIA");
			points = rset.getInt("POINTS");
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		return new QuestionContents(cat, title, criteria, points);
	}
	
	/**
	 * Grab instructions from database. Bold the keywords by source file names
	 * @param conn A database connection
	 * @param qID question id in database
	 */
	public String readInstruction(int qID, int ver)
	{
		String instruction = "";
		ArrayList<String> keywords = new ArrayList<String>();
		try
		{
			PreparedStatement qOutput = conn.prepareStatement(
			     "SELECT instructions FROM QUESTION_CONTENT "+
			     "INNER JOIN QUESTION ON QUESTION.question_content_id = "+
			          "QUESTION_CONTENT.question_content_id "+
			     "WHERE question_id = ? AND q_version="+
			          "question.q_version=(SELECT MAX(q_version) FROM question_content q "+
			               "WHERE q.q_version<=?)");
			qOutput.setInt(1, qID);
			qOutput.setInt(2, ver);
			ResultSet qResult = qOutput.executeQuery();
			
			qResult.next();

			Blob b = qResult.getBlob("INSTRUCTIONS");
			instruction = new String(b.getBytes(1, (int)b.length()));
			
			PreparedStatement keyStmt = conn.prepareStatement(
			     "select SOURCE_FILE_NAME FROM SOURCE_FILE where QUESTION_ID=?");
			keyStmt.setInt(1, qID);
			ResultSet keyResult = keyStmt.executeQuery();

			while(keyResult.next())
			{
				String [] temp = keyResult.getString("source_file_name").split("\\.");
				keywords.add(temp[0]);
			}
			for(int i = 0; i < keywords.size(); i++)
			{
				String keyword = keywords.get(i);
				if(instruction.contains(keyword))
					instruction = instruction.replace(keyword, "<b>" + keyword + "</b>");
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		return instruction;
	}
	
	/**
	 * Grab date scheduled for current exam from database.
	 * @param conn A database connection
	 * @param examID exam id in database
	 */
	public String getDate(int examID)
	{
		String examDate = "";
		try
		{
			PreparedStatement pstmt = conn.prepareStatement(
			     "SELECT DATE_SCHEDULED FROM EXAM WHERE exam_id=?");
			pstmt.setInt(1, examID);
			ResultSet rset = pstmt.executeQuery();
			
			rset.next();
			GregorianCalendar date = new GregorianCalendar();
			date.setTime((java.util.Date)rset.getObject("DATE_SCHEDULED"));
			examDate += getMonth(date.get(date.MONTH));
			examDate += Integer.toString(date.get(date.YEAR));
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		return examDate;
	}
	
	/**
	 * return month in string term based on int value.
	 * @param month int value of month
	 */
	public String getMonth(int month)
	{
		switch(month)
		{
			case 0: return "January"; case 1: return "February";  case 2: return "March";
			case 3: return "April";   case 4: return "May"; 	   case 5: return "June";
			case 6: return "July";	  case 7: return "August";    case 8: return "September";
			case 9: return "October"; case 10: return "November"; case 11: return "December";
			default: return "No Way";
		}
	}

	/**
	 * Create a zip file with the content of the directory passed in.
	 * @param dir	The directory to be zip
	 * @param zos	A ZipOutputStream where files will be written
	 * http://www.devx.com/tips/Tip/14049
	 */
	public void createZip(String dir, ZipOutputStream zos)
	{
		try
		{
			File zipDir = new File(dir);
			String[] dirList = zipDir.list();
			byte[] buffer = new byte[1000];
			int bytesIn = 0;
			
			for(int i=0;i<dirList.length;i++)
			{
				File f = new File(zipDir,dirList[i]);
				if(f.isDirectory())
				{
					String filePath = f.getPath();
					createZip(filePath, zos);
					
					continue;
				}
				
				FileInputStream fis = new FileInputStream(f);
				ZipEntry entry = new ZipEntry(f.getPath());
				zos.putNextEntry(entry);
				while((bytesIn = fis.read(buffer)) != -1)
				{
					zos.write(buffer, 0, bytesIn);
				}
				fis.close();
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}

	}
		
	private class CatAndPoints
	{
		private String cat, description;
		private int points;
		
		public CatAndPoints(String cat, int points, String description)
		{
			this.cat = cat;
			this.points = points;
			this.description = description;
		}
		
	}
	
	private class QIdAndPoints
	{
		private int qId, ver, points;
		
		public QIdAndPoints(int qId, int ver, int points)
		{
			this.qId = qId;
			this.ver = ver;
			this.points = points;
		}
	}
	
	private class QuestionContents implements Comparable
	{
		private String cat, title;
		private Blob criteria;
		private int points;
		
		public QuestionContents(String cat, String title, Blob criteria, int points)
		{
			this.cat = cat;
			this.title = title;
			this.criteria = criteria;
			this.points = points;
		}
		
		public int compareTo(Object o)
		{
			if(o instanceof QuestionContents)
			{
				QuestionContents other = (QuestionContents)o;
				return this.cat.compareTo(other.cat);
			}
			else
			{
				System.out.println("Error");
				return 0;
			}
		}
	}
}
